<template>
  <div class="flex top-view">
    <div v-for="(item, key) in topList" :key="key" :class="['top-view-item', item.label]">
      <div class="flex top-view-item-value">
        <InputNumber
          v-if="
            item.label === 'productionSet' ||
            item.label === 'badNum' ||
            item.label === 'versionLengthSet'
          "
          :min="0"
          :defaultValue="item.value + ''"
          :onUpdateValue="
            (e) => {
              return onUpdateValueFn(e, item);
            }
          "
          :needBlur="() => changeValFn(item)"
          :focus="
            () => {
              item.isChange = true;
            }
          "
          :precision="item.precision || 0"
          @addNum="changeValFn(item)"
          @reduceNum="changeValFn(item)"
        />
        <span v-else>{{ item.value }}</span>
      </div>
      <div class="top-view-item-label">
        {{ $t(`productionCenter.table.${item.label}`) }}
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import InputNumber from './InputNumber.vue';

  import { usePlcWithOut } from '@/store/modules/plc';

  import { storage } from '@/utils/Storage';

  import { useMixins } from '@/hooks/useMixins';

  import { useWsStore } from '@/store/modules/ws';

  type Props = {
    chooseItem: any;
    isAdjuest: any;
    isAutoSuccessWork: any;
    isAutoChangeOrder: any;
    orderList: any;
    canAutoSuccessWork: any;
    distributionByOrderCode: any;
    shiftData: any;
    machine: any;
    isElectron: any;
  };

  const wsStore = useWsStore();

  const { message, t } = useMixins();

  const isInitUpdateFn = ref(false);

  const isNotNaNVal = ref(false);

  const autoSuccessWorkOrder = ref(null);

  const emit = defineEmits([
    'updateOrderStatusFn',
    'autoChangeOrderFn',
    'loadOrderFn',
    'setCenterViewValFn',
    'loadWsOrderFn',
  ]);

  const props = withDefaults(defineProps<Props>(), {
    chooseItem: () => null,
    isAdjuest: () => null,
    isAutoSuccessWork: () => null,
    isAutoChangeOrder: () => null,
    orderList: () => [],
    canAutoSuccessWork: () => true,
    distributionByOrderCode: () => null,
    machine: () => null,
    shiftData: () => null,
    isElectron: () => false,
  });

  const plcStore = usePlcWithOut();

  const topList: any = ref([
    {
      label: 'orderNum',
      value: 0,
    },
    {
      label: 'productionSet',
      value: 0,
      funId: 'productionQuantitySet',
    },
    {
      label: 'productionGet',
      value: 0,
      funId: 'productionQuantityGet',
    },
    {
      label: 'adjuestNum',
      value: 0,
    },
    {
      label: 'producedNum',
      value: 0,
    },
    {
      label: 'toBeProducedNum',
      value: 0,
    },
    {
      label: 'badNum',
      value: 0,
    },
    {
      label: 'totalStackingNum',
      value: '0 / 0',
    },
  ]);

  if (props?.machine?.factoryName === 'jinchang') {
    topList.value.splice(1, 0, {
      // 版长设定
      label: 'versionLengthSet',
      funId: 'versionLengthSet',
      value: 0,
      precision: 3,
    });
  }

  console.log(props.machine);

  if (props.isAdjuest === '0') {
    const index = topList.value.findIndex((item) => item.label === 'adjuestNum');

    if (index !== -1) {
      topList.value.splice(index, 1);
    }
  }

  const orderNumItem = topList.value.find((item) => item.label === 'orderNum');

  const productionSetItem: any = topList.value.find((item) => item.label === 'productionSet');

  const productionGetItem = topList.value.find((item) => item.label === 'productionGet');

  const adjuestNumItem = topList.value.find((item) => item.label === 'adjuestNum');

  const producedNumItem = topList.value.find((item) => item.label === 'producedNum');

  const toBeProducedNumItem = topList.value.find((item) => item.label === 'toBeProducedNum');

  const totalStackingNumItem = topList.value.find((item) => item.label === 'totalStackingNum');

  const plcClick = inject('plcClick', (_obj) => {});

  const storageReportNum = ref(Number(storage.get('storageReportNum', 0)));

  const setStorageReportNumFn = (val) => {
    storageReportNum.value = val;

    storage.set('storageReportNum', val);
  };

  const getStorageReportNumFn = () => {
    return storageReportNum.value;
  };

  const onUpdateValueFn = (e, row) => {
    if (row.label === 'badNum') {
      if (e.value > producedNumItem.value || producedNumItem.value === 0) {
        message.destroyAll()

        message.error(t('productionCenter.tips.badNumError'));

        return false;
      }
    }

    console.log(e.value)

    row.isChange = true;

    row.value = e.value ? e.value : 0;

    return row.value;
  };

  const setIsChangeValueFalseFn = (item) => {
    if (item.isChangeTime) {
      clearTimeout(item.isChangeTime);

      item.isChangeTime = null;
    }

    item.isChangeTime = setTimeout(() => {
      item.isChange = false;
    }, 2000);
  };

  const changeValFn = (item) => {
    const { funId, value } = item;

    if (funId) {
      item.isChange = true;

      plcClick({ funId, value });

      setIsChangeValueFalseFn(item);
    }
  };

  const setValFn = () => {
    const {
      chooseItem,
      isAdjuest,
      isAutoSuccessWork,
      isAutoChangeOrder,
      orderList,
      canAutoSuccessWork,
      distributionByOrderCode,
      machine,
      isElectron,
    } = props;

    const newData = isElectron
      ? plcStore.newData
      : wsStore.machineCodeObj[machine.machineCode]?.plcData;

    if (chooseItem) {
      const {
        orderNum,
        producedNum,
        adjuestNum,
        pileNum,
        templateNum,
        orderStatusCode,
        adjuestSuccessTime,
        orderCode,
        materialCode,
        version,
        autoFlag,
      } = chooseItem;

      orderNumItem.value = orderNum;

      let nowProducedNum = producedNum;

      if (orderStatusCode === '30') {
        if (isAdjuest === '1') {
          if (!adjuestSuccessTime) {
            adjuestNumItem.value = productionGetItem.value || 0;
          } else {
            adjuestNumItem.value = adjuestNum || 0;
          }
        }

        if (isAutoChangeOrder === '1') {
          nowProducedNum = producedNum + (productionGetItem.value - storageReportNum.value);
        } else {
          if (isAdjuest === '1') {
            nowProducedNum = !adjuestSuccessTime ? 0 : producedNum + productionGetItem.value;
          } else {
            nowProducedNum = producedNum + productionGetItem.value;
          }
        }

        if (nowProducedNum < 0) {
          nowProducedNum = productionGetItem.value < 0 ? 0 : productionGetItem.value;
        }

        if (
          isElectron &&
          isNotNaNVal.value &&
          !autoSuccessWorkOrder.value &&
          canAutoSuccessWork &&
          distributionByOrderCode === orderCode
        ) {
          if (productionGetItem.value >= productionSetItem.value) {
            if (
              isAutoChangeOrder === '1' &&
              autoFlag === 1 &&
              orderList.length > 1 &&
              materialCode === orderList[1].materialCode &&
              version === orderList[1].version
            ) {
              // 自动换单
              if (!autoSuccessWorkOrder.value && canAutoSuccessWork) {
                autoSuccessWorkOrder.value = orderCode;

                emit('autoChangeOrderFn', orderList[1], () => {
                  autoSuccessWorkOrder.value = null;

                  emit('loadOrderFn');
                });
              }
            } else if (isAutoSuccessWork === '1') {
              // 自动完工
              autoSuccessWorkOrder.value = orderCode;

              emit(
                'updateOrderStatusFn',
                {
                  label: 'successWork',
                },
                () => {
                  autoSuccessWorkOrder.value = null;

                  emit('loadOrderFn');
                }
              );
            }
          } else {
            if (
              isAutoChangeOrder === '1' &&
              autoFlag === 1 &&
              orderList.length > 1 &&
              materialCode === orderList[1].materialCode &&
              version === orderList[1].version
            ) {
              if (nowProducedNum >= orderNum) {
                // 自动换单
                if (!autoSuccessWorkOrder.value && canAutoSuccessWork) {
                  autoSuccessWorkOrder.value = orderCode;

                  emit('autoChangeOrderFn', orderList[1], () => {
                    autoSuccessWorkOrder.value = null;

                    emit('loadOrderFn');
                  });
                }
              }
            }
          }
        }
      } else {
        if (isAdjuest === '1') {
          adjuestNumItem.value = adjuestNum || 0;
        }
      }

      producedNumItem.value = nowProducedNum;

      const toBeProducedNum = orderNum - nowProducedNum;

      toBeProducedNumItem.value = toBeProducedNum <= 0 ? 0 : toBeProducedNum;

      const totalNum = Math.ceil((nowProducedNum * (templateNum || 1)) / (pileNum || 1)); // 已生产数 × 模数 ÷ 堆叠数

      totalStackingNumItem.value = `${totalNum === 0 ? 1 : totalNum} / ${pileNum || 1}`;
    } else {
      orderNumItem.value = 0;

      if (isAdjuest === '1') {
        adjuestNumItem.value = 0;
      }

      producedNumItem.value = 0;

      toBeProducedNumItem.value = 0;

      totalStackingNumItem.value = '0 / 0';
    }

    if (isElectron && wsStore.client && wsStore.status !== 'CLOSE') {
      wsStore.client.emit('productionCenterData', {
        plcData: newData,
        orderList,
        machine,
        shiftData: props.shiftData,
      });
    }
  };

  const getValNumFn = (type) => {
    const obj = topList.value.find((item) => item.label === type);

    if (obj) {
      return obj.value;
    }

    return 0;
  };

  const setValNumFn = (type, val) => {
    const obj = topList.value.find((item) => item.label === type);

    if (obj) {
      obj.value = val;
    }
  };

  const updateFn = () => {
    const newData = props.isElectron
      ? plcStore.newData
      : wsStore.machineCodeObj[props.machine.machineCode]?.plcData;

    if (!productionSetItem.isChange) {
      productionSetItem.value = isNaN(parseInt(newData[productionSetItem.funId as any]))
        ? 0
        : parseInt(newData[productionSetItem.funId as any]);
    }

    // !productionSetItem.isChange &&

    productionGetItem.value = isNaN(parseInt(newData[productionGetItem.funId as any]))
      ? 0
      : parseInt(newData[productionGetItem.funId as any]);

    if (
      isNaN(parseInt(newData[productionGetItem.funId as any])) ||
      isNaN(parseInt(newData[productionSetItem.funId as any]))
    ) {
      isNotNaNVal.value = false;
    } else {
      isNotNaNVal.value = true;
    }

    setValFn();
  };

  defineExpose({
    getValNumFn,
    setStorageReportNumFn,
    getStorageReportNumFn,
    setValNumFn,
    setValFn,
  });

  nextTick(() => {
    // updateFn();

    if (props.isElectron) {
      plcStore.$subscribe((_mutation, _state) => {
        updateFn();

        emit('setCenterViewValFn');
      });
    } else {
      wsStore.$subscribe((_mutation, _state) => {
        updateFn();

        emit('setCenterViewValFn');

        emit('loadWsOrderFn');
      });
    }

    watch(
      props,
      (_val) => {
        if (isInitUpdateFn.value) {
          setValFn();
        }
      },
      { immediate: true, deep: true }
    );

    nextTick(() => {
      updateFn();

      isInitUpdateFn.value = true;
    });
  });
</script>

<style lang="less" scoped>
  .top-view {
    justify-content: space-between;
    background-color: #fff;
    padding: 8px 0;
    border-radius: 4px;

    .top-view-item {
      padding: 8px 4px;
      text-align: center;
      font-size: 18px;
      color: #999;
      flex: 1;

      .top-view-item-value {
        font-size: 26px;
        color: #666;
        height: 48px;
        align-items: center;
        justify-content: center;
        :deep(.DFModalKeyboardInput-input),
        :deep(.DFModalKeyboard) {
          .n-input .n-input__input-el {
            padding: 0 !important;
            height: 48px !important;
            line-height: 48px !important;
            font-size: 26px;
          }
          .n-input {
            border-radius: 0 !important;

            .n-input__suffix {
              margin-left: 0;
            }
          }

          .n-input-wrapper {
            padding-right: 8px !important;
          }
        }
      }
      .top-view-item-label {
        margin-top: 8px;
      }
    }
  }
</style>
